

#include "cybertron/core/UtilTime.hpp"
#include "../PlatformHeader.hpp"
#include <atomic>
#include <chrono>

CYBERTRON_BEGIN

CybertronCoreAPI void UtilTime::getLocalTime(struct tm& timeinfo)
{
	time_t rawtime;
	time(&rawtime);

#ifdef CYBERTRON_WIN
	localtime_s(&timeinfo, &rawtime);
#else
	localtime_r(&rawtime, &timeinfo);
#endif
}

CybertronCoreAPI std::string UtilTime::getLocalTimeStringForFile()
{
	struct tm timeinfo;
	getLocalTime(timeinfo);

	char timeBuffer[80];
	strftime(timeBuffer, sizeof(timeBuffer), "%Y%m%d%I%M%S", &timeinfo);

	return timeBuffer;
}

CybertronCoreAPI std::string UtilTime::getLocalTimeStringForPrint()
{
	struct tm timeinfo;
	getLocalTime(timeinfo);

	char timeBuffer[80];
	strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M:%S", &timeinfo);

	return std::string(timeBuffer);
}

CybertronCoreAPI std::string UtilTime::getLocalTimeStringForPrint24HourFormat()
{
	struct tm timeinfo;
	getLocalTime(timeinfo);

	char timeBuffer[80];
	strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", &timeinfo);

	return std::string(timeBuffer);
}

std::atomic<unsigned int> gMilliseconds;

std::chrono::high_resolution_clock::time_point getAppStartTime()
{
	static std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
	return t;
}

CybertronCoreAPI unsigned int UtilTime::millisecondsCurrent()
{
	return gMilliseconds;
}

CybertronCoreAPI void UtilTime::millisecondsUpdate()
{
	std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
	std::chrono::nanoseconds span = t - getAppStartTime();
	unsigned int ms = (unsigned int)(span.count() / 1000000);

	gMilliseconds = ms;
}

CybertronCoreAPI void UtilTime::millisecondsUpdate(unsigned int ms)
{
	gMilliseconds = ms;
}

CybertronCoreAPI unsigned long UtilTime::getTimeStampSeconds()
{
	std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
	auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
	std::time_t timestamp = tmp.count();
	unsigned long temp = (unsigned long)(timestamp/1000);
	//std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
	return temp;
}

CYBERTRON_END
